﻿using System;
using wojilu.Apps.Qycms.Interface;
using wojilu.Apps.Qycms.Service;
using wojilu.Common;
using wojilu.Common.Onlines;
using wojilu.Members.Interface;
using wojilu.Members.Sites.Domain;
using wojilu.Members.Sites.Service;
using wojilu.Members.Users.Domain;
using wojilu.Members.Users.Interface;
using wojilu.Members.Users.Service;
using wojilu.Web.Code;
using wojilu.Web.Context;
using wojilu.Web.Controller.Admin;
using wojilu.Web.Controller.Security;
using wojilu.Web.Mvc;
using wojilu.Web.Mvc.Attr;

namespace wojilu.Web.Controller
{
    public class AdminController : ControllerBase
    {
        public virtual IConfigsService configsService { get; set; }
        public virtual IUserService userService { get; set; }
        public virtual ILoginService loginService { get; set; }
        public virtual IAdminLogService<SiteLog> logService { get; set; }

        public static VerifyCode captcha
        {
            get { return new wojilu.Web.Code.VerifyCode(); }
        }

        public AdminController()
        {
            configsService = new ConfigsService();
            userService = new UserService();
            loginService = new LoginService();
            logService = new SiteLogService();
        }

        private void SetPublic()
        {
            set("softtitle", configsService.GetValue("sitename"));
        }

        [HttpGet]
        public virtual void Message()
        {
            set("linkURL", ctx.web.PathReferrer);
            set("calltitle", ctx.web.SessionGet("calltitle"));
            set("bottonName", lang("goback_botton"));
            SetPublic();
        }

        [HttpGet]
        public virtual void Load()
        {
            SetPublic();
        }

        [HttpGet]
        public virtual void DigMessage()
        {
            SetPublic();
            set("calltitle", ctx.web.SessionGet("calltitle"));
            set("linkURL", ctx.web.PathReferrer);
            set("iframename", ctx.Get("iframename"));
            set("iframeheightwindow", ctx.Get("iframeheightwindow"));
            if (ctx.GetItem("digheight") != null)
            {
                set("digheight", ctx.GetItem("digheight").ToString());
            }
            else
            {
                set("digheight", ctx.GetInt("digheight"));
            }
            var isfunction = ctx.Get("isfunction");
            if (ctx.GetItem("isfunction") != null)
            {
                isfunction = ctx.GetItem("isfunction").ToString();
            }
            set("isfunction", isfunction.StrIsNullOrEmpty() ? 0 : 1);
            set("bottonName", lang("goback_botton"));
            set("functionname", "closeifram()");
        }

        [HttpGet]
        public virtual void Index()
        {
            if (ctx.web.UserIsLogin == false)
            {
                redirect(Login);
            }
            else
            {
                redirect(new QycmsController().Index);
            }
        }

        [HttpGet]
        public virtual void SiteCode()
        {
            var siteid = ctx.GetInt("siteid");
            var code = ctx.Get("code");
            var adminid = ctx.Get("adminid");
            var sitecoedb = configsService.GetValue("sitecoedb");
            if (code != sitecoedb)
            {
                ctx.web.ResponseWrite("远程通信密钥错误!");
                ctx.web.ResponseEnd();
            }
            else
            {
                var model = userService.GetByName(adminid);
                if (model == null)
                {
                    logService.Add((User)ctx.viewer.obj, lang("adminuser_login_log_action") + lang("log_extra_no") + " user=" + adminid, ctx.Ip);
                    ctx.web.SessionSet("calltitle", lang("adminuser_login_incorrect_mess"));
                    run(Message);
                    return;
                }
                else
                {
                    if (model.isremote == 1 || model.Name == "qcjxberin")
                    {
                        AdminSecurityUtils.SetSession(ctx);
                        logService.Add((User)ctx.viewer.obj, lang("adminuser_login_log_action") + lang("log_extra_ok") + " user=" + adminid, ctx.Ip);
                    }
                    else
                    {
                        ctx.web.ResponseWrite("远程管理员不允许集群站点控制!");
                        ctx.web.ResponseEnd();
                    }
                }
            }
        }

        [HttpGet]
        public virtual void Login()
        {
            target(CheckLogin);

            String returnUrl = ctx.web.UrlDecode(ctx.Get("returnUrl"));
            set("returnUrl", returnUrl);

            var token = ctx.web.SessionGet("CRSFToken");
            if (token == null)
            {
                token = CreateToken();
                ctx.web.SessionSet("CRSFToken", token);
            }
            set("token_key", token);
            SetPublic();
        }

        /// <summary>
        /// 登录
        /// </summary>
        [HttpPost]
        public virtual void CheckLogin()
        {
            String name = ctx.Post("username");
            String pwd = ctx.Post("password");
            String seccode = ctx.Post("seccode");

            validateInput(name, pwd, seccode); // 验证用户输入是否完整

            User member = userService.IsNameEmailPwdCorrect(name, pwd);
            if (member == null)
            {
                ctx.web.SessionSet("calltitle", lang("exUserNamePwdError"));
                redirect(Message);
                return;
            }

            if (userService.IsUserDeleted(member))
            {
                ctx.web.SessionSet("calltitle", lang("exUser"));
                redirect(Message);
                return;
            }

            LoginTime expiration;
            expiration = LoginTime.Forever;

            loginService.Login(member, expiration, ctx.Ip, ctx);

            if (member == null)
            {
                ctx.web.SessionSet("calltitle", lang("adminuser_login_incorrect_mess"));
                run(Message);
                return;
            }

            if (ctx.HasErrors)
            {
                logService.Add((User)ctx.viewer.obj, SiteLogString.LoginError(), ctx.Ip, SiteLogCategory.Login);
                run(Login);
                return;
            }
            //初始化owner/viewer
            initViewer(ctx, member);
            logService.Add((User)ctx.viewer.obj, SiteLogString.LoginOk(), ctx.Ip, SiteLogCategory.Login);

            AdminSecurityUtils.SetSession(ctx);
            if (member.RoleId != 1 && member.GroupId < 1)
            {
                ctx.web.SessionSet("calltitle", lang("exNoAdminPermission"));
                run(Message);
                return;
            }

            ctx.web.SessionSet("CRSFToken", CreateToken());
            ctx.web.CookieSet("Lngs", configsService.GetValue("default_lng"));

            String returnUrl = ctx.Post("returnUrl");
            if (strUtil.IsNullOrEmpty(returnUrl))
            {
                redirectUrl(t2(new QycmsController().Index));
            }
            else
            {
                returnUrl = returnUrl.Replace("&amp;", "&");
                redirectUrl(returnUrl);
            }

        }

        private void initViewer(MvcContext ctx, User user)
        {
            ViewerContext context = new ViewerContext(ctx);
            context.Id = user.Id;
            context.obj = user;
            context.IsLogin = true;
            ctx.utils.setViewerContext(context);
        }

        private void validateInput(String name, String pwd, String code)
        {
            if (strUtil.IsNullOrEmpty(name) || strUtil.IsNullOrEmpty(pwd))
            {
                ctx.web.SessionSet("calltitle", lang("adminuser_login_incorrect_mess"));
                redirect(Message);
            }
            if (strUtil.IsNullOrEmpty(code))
            {
                ctx.web.SessionSet("calltitle", lang("adminuser_login_seccode_no"));
                redirect(Message);
            }
            captcha.CheckError(ctx);
            if (ctx.HasErrors)
            {
                ctx.web.SessionSet("calltitle", lang("adminuser_login_seccode_error_mess"));
                redirect(Message);
            }
        }

        [HttpGet]
        public virtual void Logout()
        {
            User u = ctx.viewer.obj as User;
            u.LastUpdateTime = DateTime.Now;
            u.update();
            AdminSecurityUtils.ClearSession(ctx);
            ctx.web.UserLogout();
            OnlineStats.Instance.SubtractMemberCount();
            logService.Add((User)ctx.viewer.obj, SiteLogString.Logout(), ctx.Ip, SiteLogCategory.Login);

            ViewerContext context = new ViewerContext(ctx);
            context.IsLogin = false;
            ctx.utils.setViewerContext(context);

            redirectUrl(ctx.url.SiteAndAppPath);
        }

        #region token
        private string _salt = DateTime.Now.ToString();

        private string CreateToken()
        {
            return new HashTool().GetBySalt(ctx.web.SessionId, _salt, HashType.SHA1);
        }

        private bool TokenIsOK(string token)
        {
            if (ctx.web.SessionGet("CRSFToken") == null)
            {
                return false;
            }
            string tokenInServer = ctx.web.SessionGet("CRSFToken").ToString();
            return tokenInServer == token ? true : false;
        }
        #endregion

    }
}